//@ts-check

import sha256 from 'crypto-js/sha256';
import {
  WebDB
} from "aomd-web-db";
import {
  AEvent
} from "aomd-utils/src/event/AEvent";
import { RequestEntity } from './model/RequestEntity';


/**
 * 
 *
 * @class CacheBorderLoader
 * @extends {AEvent}
 */
class CacheBorderLoader extends AEvent {

  constructor(option) {
    super();

    this._event = {
      'error': [],
      'success': [],
      'progress': [],
    }

    // 待加载的资源列表
    this.loaderList = [];

    this.index = 0;

    this._initDB(option)
  }
  /**
   * 初始化 数据库
   *
   * @memberof CacheBorderLoader
   */
  _initDB(option) {
    this.db = WebDB.getInstance(option);
    this.db.on("upgradeneeded", function () {
      // 创建表名
      var objectStore = WebDB.getInstance().createObjectStore(CacheBorderLoader.TABLENAME);
      // raw 添加索引
      // objectStore.createIndex()
    });
    this.db.init()
  }


  //ES6类的静态方法（只能直接由类名调用的方法）：static getInstance
  //ES6类的静态属性：直接挂载在类名上的方法，如：CacheBorderLoader['instance']()

  static TABLENAME = 'loader'

  static sha256(string) {
    var sha256string = sha256(string)
    return sha256string.toString();
  }

  /**
   *获取 实例
   *
   * @static
   * @returns
   * @memberof CacheBorderLoader
   */
  static getInstance() {
    // 使用单例模式 初始化对象
    if (!CacheBorderLoader['instance']) {
      CacheBorderLoader['instance'] = new CacheBorderLoader();
      return CacheBorderLoader['instance']
    }
    return CacheBorderLoader['instance'];
  }

  /**
   * 删除指定id缓存
   *
   * @memberof CacheBorderLoader
   */
  delCache(id) {
    this.db.delByKey(CacheBorderLoader.TABLENAME, id)
  }

  /**
   * 清除所有
   *
   * @memberof CacheBorderLoader
   */
  clearCache() {
    this.db.clear(CacheBorderLoader.TABLENAME)
  }

  /**
   * 批量加载资源
   *
   * @param {*} [modelList=[]]
   * @memberof CacheBorderLoader
   */
  loaders(modelList = []) {
    for (var item of modelList) {
      this.loader(item)
    }
  }

  /**
   * 加载资源
   *
   * @memberof CacheBorderLoader
   */
  loader(loaderEntity) {
    this.db.on('init', () => {

      let requestEntity = new RequestEntity(loaderEntity);

      requestEntity.on('success', (data) => {
        if (data.type !== 'readDB') {
          // 不是数据库读取 则储存到数据库
          this.db.saveKey(CacheBorderLoader.TABLENAME, {
            payloads: data.entity.payloads,
            expire: data.entity.expire
          }, data.entity.uid)
        }


        var { totalSize, entityIndex, totalProgress, completedNumber } = this._computedSpeed(requestEntity)

        this._emit('success', { entity: requestEntity, entityIndex, totalSize, totalProgress, completedNumber })
      })

      requestEntity.on('error', (data) => {

        var { totalSize, entityIndex, totalProgress, completedNumber } = this._computedSpeed(requestEntity)
        this._emit('error', { entity: requestEntity, entityIndex, totalSize, totalProgress, completedNumber })

      })


      requestEntity.on('progress', (data) => {

        var { totalSize, entityIndex, totalProgress, completedNumber } = this._computedSpeed(requestEntity)
        this._emit('progress', { entity: requestEntity, entityIndex, totalSize, totalProgress, completedNumber })

      })

      // 读取数据库
      this.db.getByKey(CacheBorderLoader.TABLENAME, CacheBorderLoader.sha256(loaderEntity['url']))
        .then((data) => {
          if (data.entity && (data.entity['expire'] == 0 || data.entity['expire'] > Date.now())) {
            requestEntity.payloads = data.entity.payloads

            requestEntity.progress = 100

            requestEntity.status = true

            requestEntity._emit('success', { entity: requestEntity, e: {}, type: 'readDB' })
          } else {
            requestEntity.send()
          }
        })
        .catch((data) => {
          requestEntity.send()
        })

      this.loaderList.push(requestEntity)
    })
  }

  /**
   * 计算 资源进度相关内容
   *
   * @param {*} entity
   * @returns
   * @memberof CacheBorderLoader
   */
  _computedSpeed(entity) {

    var itemProgress = 0;
    var itmeCompletedNumber = 0
    for (var item of this.loaderList) {
      itemProgress += item.progress
      if (item.status) {
        itmeCompletedNumber += 1
      }
    }

    return {
      // 完成数量
      completedNumber: itmeCompletedNumber,
      // 总进度
      totalProgress: itemProgress / this.loaderList.length,
      // 总个数
      totalSize: this.loaderList.length,
      // 当前实体下标
      entityIndex: this.loaderList.indexOf(entity)
    }
  }
}

export {
  CacheBorderLoader
}